﻿using Demo.Domains.Entities.Sys;
using Demo.PetaPoco.Application.Dtos.Menu;

namespace Demo.PetaPoco.Application.Services.Menu;

public static class MenuConverter
{
	/// <summary>
	/// 将 SysMenu 实体集合转换为带子级的 RouteRecord 集合。
	/// </summary>
	/// <param name="menus">系统菜单实体集合</param>
	/// <returns>带子级的 RouteRecord 列表</returns>
	public static List<RouteRecord> ToRouteRecordDtos(IEnumerable<SysMenu> menus)
	{
		if (menus == null || !menus.Any())
			return new List<RouteRecord>();

		// 将所有菜单转换为 DTO，并存储在字典中便于查找
		var menuDict = menus.ToDictionary(
			m => m.Id,
			m => ConvertToRouteRecordDto(m)
		);

		// 构建树状结构
		var rootMenus = new List<RouteRecord>();

		foreach (var menu in menus)
		{
			var dto = menuDict[menu.Id];

			if (!menu.ParentId.HasValue || menu.ParentId == 0)
			{
				// 顶级菜单（没有父级或 ParentId 为 0）
				rootMenus.Add(dto);
			}
			else if (menuDict.ContainsKey(menu.ParentId.Value))
			{
				// 有父级菜单，将当前 DTO 添加到父级的 Children 中
				var parentDto = menuDict[menu.ParentId.Value];
				var children = parentDto.Children ?? new List<RouteRecord>();
				children.Add(dto);
				parentDto.Children = children;
			}
		}

		// 根据 Sort 属性对菜单排序
		SortRouteRecords(rootMenus);

		return rootMenus;
	}

	/// <summary>
	/// 将单个 SysMenu 转换为 RouteRecord。
	/// </summary>
	/// <param name="menu">系统菜单实体</param>
	/// <returns>转换后的 RouteRecord</returns>
	private static RouteRecord ConvertToRouteRecordDto(SysMenu menu)
	{

		object? alias = null;
		if (!string.IsNullOrEmpty(menu.Alias))
		{
			string[] aliasArray = menu.Alias.Split(',');
			if (aliasArray.Length <= 1)
				alias = menu.Alias;
			else
				alias = aliasArray;
		}

		return new RouteRecord
		{
			Component = menu.Component ?? string.Empty,
			Name = menu.Name, // 使用 Code 作为唯一名称
			Path = menu.Path,
			Alias = alias, // 如果需要支持别名，可以从其他字段映射
			Redirect = menu.Redirect, // 如果 SysMenu 有重定向字段，可以映射
			Meta = new RouteMeta
			{
				Title = menu.Title,
				Icon = menu.Icon,
				HideInMenu = menu.IsHide,
				Order = menu.Order,
				HideInTab = menu.HideTab,
				ActiveIcon = menu.ActiveIcon,
				OpenInNewWindow = menu.OpenNewWindow,
				Link = menu.Link,
				// 如果 SysMenu 有其他字段需要映射，可以继续添加
				// 其他 Meta 属性可以根据需求映射，例如：
				// Authority = menu.SomeAuthorityField?.Split(',')?.ToList(),
				// KeepAlive = menu.SomeKeepAliveField
			},
			Props = null // 如果需要支持 Props，可以从其他字段映射
		};
	}

	/// <summary>
	/// 对 RouteRecord 列表及其子级进行递归排序。
	/// </summary>
	/// <param name="routeRecords">待排序的路由记录列表</param>
	private static void SortRouteRecords(List<RouteRecord> routeRecords)
	{
		if (routeRecords == null || !routeRecords.Any())
			return;

		// 按 Meta.Order 升序排序
		routeRecords.Sort((a, b) => (a.Meta?.Order ?? 0).CompareTo(b.Meta?.Order ?? 0));

		// 递归排序每个节点的子级
		foreach (var route in routeRecords)
		{
			var children = route.Children ?? new List<RouteRecord>();
			if (children.Any())
			{
				SortRouteRecords(children);
				route.Children = children;
			}
		}
	}
}
